package com.xmg.forkjoin;

import lombok.extern.slf4j.Slf4j;
import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.LongStream;

@Slf4j(topic = "c.ForkJoinTest")
public class ForkJoinTest {


    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException, InstantiationException {
//        long oldStart = System.currentTimeMillis();
//        ForkJoinPool pool = new ForkJoinPool(3);
//        System.out.println(pool.invoke(new ForkJoinCalculate(0l,10000000000l)));
//        System.out.println("old cost:"+(System.currentTimeMillis()-oldStart));
//
//        long newStart = System.currentTimeMillis();
//        long sum = LongStream.rangeClosed(1, 10000000000l).parallel().sum();
//        System.out.println("new cost:"+(System.currentTimeMillis()-newStart));

//        new ReentrantReadWriteLock().readLock().newCondition().await();
        Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
        theUnsafe.setAccessible(true);
        Unsafe unsafe = (Unsafe)theUnsafe.get(null);
        long state = unsafe.objectFieldOffset(User.class.getDeclaredField("name"));
        System.out.println(state);

        Class<?> user = Class.forName("com.xmg.forkjoin.User");
        User instance = (User) user.newInstance();
        System.out.println(unsafe.objectFieldOffset(user.getDeclaredField("id")));
    }

}

class User {
    int id;
    String name;
}

class MyTask extends RecursiveTask<Long>{

    private long n;

    public MyTask(long n) {
        this.n = n;
    }

    @Override
    protected Long compute() {
        if(n==1){
            return 1l;
        }
        MyTask t1 = new MyTask(n - 1);
        t1.fork();//让一个线程去执行任务

        long result = n + t1.join();
        return result;
    }
}

class MyTask2 extends RecursiveTask<Long>{

    Long begin,end;

    public MyTask2(Long begin, Long end) {
        this.begin = begin;
        this.end = end;
    }

    @Override
    protected Long compute() {
        if(begin == end){
            return begin;
        }
        if(end-begin ==1){
            return end + begin;
        }

        Long mid = (end + begin) / 2;
        MyTask2 t1 = new MyTask2(begin, mid);
        t1.fork();
        MyTask2 t2 = new MyTask2(mid + 1, end);
        t2.fork();

        Long result = t1.join() + t2.join();
        return result;
    }


}
class ForkJoinCalculate extends RecursiveTask<Long> {

    private long start;
    private long end;

    private static final long THRESHOLD = 10000L; // 临界值

    public ForkJoinCalculate(long start, long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        long length = end - start;

        if (length <= THRESHOLD) {
            long sum = 0;
            for (long i = start; i <= end; i++) {
                sum += i;
            }
            return sum;
        } else {
            long middle = (start + end) / 2;

            ForkJoinCalculate left = new ForkJoinCalculate(start, middle);
            left.fork(); // 拆分，并将该子任务压入线程队列

            ForkJoinCalculate right = new ForkJoinCalculate(middle + 1, end);
            right.fork();

            return left.join() + right.join();
        }
    }
}
